/*****************************************************************************
* Keppe Messenger (KMP) Keppe Project-Team User Messaging System
* Copyright (C) 2013-2014 Keppe Project-Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

#include "frmChat.h"
#include "frmLogin.h"
#include "ui_frmChat.h"
#include <QDir>
#include <QMenu>
#include <QTime>
#include <QStyle>
#include <QDebug>
#include <QTimer>
#include <QSettings>
#include <QScrollBar>
#include <QMessageBox>
#include <QStyleFactory>
#include <QDesktopServices>
#ifdef QT5
#include <QStandardPaths>
#endif
frmChat::frmChat(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::frmChat)
{
    setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint^Qt::WindowMinMaxButtonsHint);
    ui->setupUi(this);
    ui->tbChat->setOpenAutoBrowser(false);
    setWidgetDesign();
    cultid = 0;
}

void frmChat::setForm(frmLogin* login)
{
    form = login;
}

void frmChat::setChatter(QString username, QString nickname, QString userstate, QString myname, QString stateImage, int onlinestate, QString avatarImage, bool reloadConf)
{
    frmLogin *login = (frmLogin*)form;
    this->setWindowTitle(nickname);
#ifdef QT4
    QString msgPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.kmsg";
    msgPath = msgPath.replace("\\","/");
    msgPath = msgPath.replace("//","/");
    QDir dir;
    dir.mkpath(msgPath);
#elif defined(QT5)
    QString msgPath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.kmsg";
    msgPath = msgPath.replace("\\","/");
    msgPath = msgPath.replace("//","/");
    QDir dir;
    dir.mkpath(msgPath);
#endif
    if (cuavri != avatarImage)
    {
        QImage avatarPiximg = login->getAvatarImage(avatarImage);
        if (!avatarPiximg.isNull())
        {
            QPixmap avatarPixmap = QPixmap::fromImage(avatarPiximg);
            ui->labUserAvatar->setPixmap(avatarPixmap);
        }
    }
    cuname = username;
    cunick = nickname;
    mynick = myname;
    if (reloadConf)
    {
        QString msglogPath = msgPath + "/" + username + ".ini";
        msgs = new QSettings(msglogPath,QSettings::IniFormat);
        msgs->beginGroup("Chat");
        culast = msgs->value("LastMessageFrom","").toString();
        cultid = msgs->value("LastMessageID",0).toInt();
        msgs->endGroup();
        msgs->beginGroup("Messages");
        int beginFrom = 1;
        int workInt = 0;
        bool firstInt = true;
        QStringList emptyList;
        if (cultid > 1000)
        {
            beginFrom = cultid - 1000;
            workInt = beginFrom - 1;
        }
        while(workInt != cultid)
        {
            int msgInt = workInt + 1;
            if (firstInt)
            {
                firstInt = false;
                QStringList msg = msgs->value("Message" + QString::number(msgInt),emptyList).toStringList();
                QString message;
                if (msg.length() >= 3)
                {
                    message = msg.at(0);
                    if (msg.at(2) == "false")
                    {
                        QString nick;
                        if (msg.at(1) == "You")
                        {
                            nick = mynick;
                            message = "<span style=\"color: grey\">" + nick + "</span><br>" + message;
                        }
                        else if(msg.at(1) == "She/He")
                        {
                            nick = cunick;
                            message = "<span style=\"color: blue\">" + nick + "</span><br>" + message;
                        }
                        else
                        {
                            nick = QApplication::tr("Unknown");
                            message = "<span style=\"color: red\">" + nick + "</span><br>" + message;
                        }
                    }
                }
                ui->tbChat->append(message);
            }
            else
            {
                QStringList msg = msgs->value("Message" + QString::number(msgInt),emptyList).toStringList();
                QString message;
                if (msg.length() >= 3)
                {
                    message = msg.at(0);
                }
                ui->tbChat->append(message);
            }
            workInt++;
        }
        msgs->endGroup();
        // Fix Scroll Bug
        QTimer::singleShot(10,this,SLOT(scrollDown()));
        // Restore Old Geometry
        QByteArray oldGeometry;
        QSettings settings(ProductVendor,ProductName);
        settings.beginGroup("Windows");
        settings.beginGroup("Chat");
        if (settings.contains(username))
        {
            oldGeometry = settings.value(username).toByteArray();
        }
        settings.endGroup();
        settings.endGroup();
        if (oldGeometry != "")
        {
            restoreGeometry(oldGeometry);
        }
    }
    ui->labChatUname->setText("<span style=\"color: blue;\" title=\"" + username + "\">" + nickname + "</span>");
    ui->labAccount->setText(username);
    if (userstate.trimmed() != "")
    {
        ui->labStatusText->setText(userstate);
    }
    else
    {
        ui->labStatusText->setText(login->getTaskBarOnlineStateStringFromID(onlinestate));
    }
    ui->labStatus->setPixmap(QPixmap(stateImage));
    ui->labStatusImage->setPixmap(QPixmap(stateImage));
    QSettings settings(ProductVendor,ProductName);
    settings.beginGroup("Interface");
    QString currentFontString = settings.value("Font","").toString();
    QFont currentFont;
    bool ok = currentFont.fromString(currentFontString);
    if (ok)
    {
        if (currentFont != ui->tbChat->font())
        {
            if (currentFontString != "")
            {
                ui->tbChat->setFont(currentFont);
                ui->txtMessageBox->setFont(currentFont);
            }
            else
            {
                QFont systemFont;
                ui->tbChat->setFont(systemFont);
                ui->txtMessageBox->setFont(systemFont);
            }
        }
    }
    settings.endGroup();
}

void frmChat::automaticLength()
{
    //ui->txtMessageBox->setMinimumSize(ui->layout1->geometry().width(), 35);
    //QTimer::singleShot(10,this,SLOT(automaticLength()));
}

void frmChat::closeEvent(QCloseEvent *)
{
    if (cuname != "")
    {
        QSettings settings(ProductVendor,ProductName);
        settings.beginGroup("Windows");
        settings.beginGroup("Chat");
        settings.setValue(cuname,saveGeometry());
        settings.endGroup();
        settings.endGroup();
    }
    msgs->deleteLater();
    frmLogin* login = (frmLogin*)form;
    login->removeMe(cuname);
    deleteLater();
}

frmChat::~frmChat()
{
    delete ui;
}

void frmChat::incomingMessage(QString message)
{
    if (culast != "She/He")
    {
        cultid++;
        culast = "She/He";
        QStringList msg;
        msg.append("<span style=\"color: blue\">" + cunick + "</span><br><span>" + convertMessage(message) + "</span>");
        msg.append(culast);
        msg.append("true");
        ui->tbChat->append(msg.at(0));
        msgs->beginGroup("Chat");
        msgs->setValue("LastMessageFrom","She/He");
        msgs->setValue("LastMessageID",cultid);
        msgs->endGroup();
        msgs->beginGroup("Messages");
        msgs->setValue("Message" + QString::number(cultid),msg);
        msgs->endGroup();
    }
    else
    {
        cultid++;
        culast = "She/He";
        QStringList msg;
        msg.append("<span>" + convertMessage(message) + "</span>");
        msg.append(culast);
        msg.append("false");
        ui->tbChat->append(msg.at(0));
        msgs->beginGroup("Chat");
        msgs->setValue("LastMessageFrom","She/He");
        msgs->setValue("LastMessageID",cultid);
        msgs->endGroup();
        msgs->beginGroup("Messages");
        msgs->setValue("Message" + QString::number(cultid),msg);
        msgs->endGroup();
    }
}

QString frmChat::getChatTime()
{
    QString hour;
    QString minute;
    QString second;
    hour = QString::number(QTime::currentTime().hour());
    minute = QString::number(QTime::currentTime().minute());
    second = QString::number(QTime::currentTime().second());
    if (hour.length() == 1) hour = hour.insert(0,"0");
    if (minute.length() == 1) minute = minute.insert(0,"0");
    if (second.length() == 1) second = second.insert(0,"0");
    QString times = "(" + hour + ":" + minute + ")";
    return times;
}

void frmChat::sendMessage()
{
    frmLogin* login = (frmLogin*)form;
    if (login->isConnectedWithServer())
    {
        QString text = QString::fromUtf8(ui->txtMessageBox->text().toUtf8());
        text.replace(QString::fromUtf8("&"),"&amp;");
        text.replace(QString::fromUtf8("<"),"&lt;");
        text.replace(QString::fromUtf8(">"),"&gt;");
        text.replace(QString::fromUtf8("\""),"&quot;");
        text.replace(QString::fromUtf8("ä"),"&auml;");
        text.replace(QString::fromUtf8("ö"),"&ouml;");
        text.replace(QString::fromUtf8("ü"),"&uuml;");
        text.replace(QString::fromUtf8("Ä"),"&Auml;");
        text.replace(QString::fromUtf8("Ö"),"&Ouml;");
        text.replace(QString::fromUtf8("Ü"),"&Uuml;");
        text.replace(QString::fromUtf8("ß"),"&szlig;");
        text.replace(QString::fromUtf8("€"),"&euro;");
        text.replace(QString::fromUtf8("§"),"&sect;");
        text.replace(QString::fromUtf8("©"),"&copy;");
        text.replace(QString::fromUtf8("®"),"&reg;");
        text.replace(QString::fromUtf8("°"),"&deg;");
        text.replace(QString::fromUtf8("²"),"&sup2;");
        text.replace(QString::fromUtf8("³"),"&sup3;");
        text.replace(QString::fromUtf8("\r\n"),"<br>");
        text.replace(QString::fromUtf8("\r"),"<br>");
        text.replace(QString::fromUtf8("\n"),"<br>");
        if (text.trimmed() == QString("")) return;
        int ret = login->sendMessage(cuname,text);
        ui->txtMessageBox->clear();
        if (ret == 404 || ret == 1)
        {
            if (culast != "KM")
            {
                culast = "KM";
                QStringList msg;
                msg.append("<span style=\"color: red\">" + QString(ProductName) + "</span><br><span>" + QApplication::tr("%1 is offline").arg(cunick) + "</span>");
                ui->tbChat->append(msg.at(0));
            }
            else
            {
                culast = "KM";
                QStringList msg;
                msg.append("<span>" + QApplication::tr("%1 is offline").arg(cunick) + "</span>");
                ui->tbChat->append(msg.at(0));
            }
        }
        else if (ret == 200)
        {
            if (culast != "You")
            {
                cultid++;
                culast = "You";
                QStringList msg;
                msg.append("<span style=\"color: grey\">" + mynick + "</span><br><span>" + convertMessage(text) + "</span>");
                msg.append(culast);
                msg.append("true");
                ui->tbChat->append(msg.at(0));
                msgs->beginGroup("Chat");
                msgs->setValue("LastMessageFrom","You");
                msgs->setValue("LastMessageID",cultid);
                msgs->endGroup();
                msgs->beginGroup("Messages");
                msgs->setValue("Message" + QString::number(cultid),msg);
                msgs->endGroup();
            }
            else
            {
                cultid++;
                culast = "You";
                QStringList msg;
                msg.append("<span>" + convertMessage(text) + "</span>");
                msg.append(culast);
                msg.append("false");
                ui->tbChat->append(msg.at(0));
                msgs->beginGroup("Chat");
                msgs->setValue("LastMessageFrom","You");
                msgs->setValue("LastMessageID",cultid);
                msgs->endGroup();
                msgs->beginGroup("Messages");
                msgs->setValue("Message" + QString::number(cultid),msg);
                msgs->endGroup();
            }
        }
        else
        {
            if (culast != "You")
            {
                cultid++;
                culast = "You";
                QStringList msg;
                msg.append("<span style=\"color: grey\">" + mynick + "</span><br><span>" + convertMessage(text) + " ---&nbsp;<a href=\"kmp://msgmaybenotdelivered\"><img src=\":/img/mail-t2x16.png\"/></a></span>");
                msg.append(culast);
                msg.append("true");
                ui->tbChat->append(msg.at(0));
                msgs->beginGroup("Chat");
                msgs->setValue("LastMessageFrom","You");
                msgs->setValue("LastMessageID",cultid);
                msgs->endGroup();
                msgs->beginGroup("Messages");
                msgs->setValue("Message" + QString::number(cultid),msg);
                msgs->endGroup();
            }
            else
            {
                cultid++;
                culast = "You";
                QStringList msg;
                msg.append("<span>" + convertMessage(text) + " ---&nbsp;<a href=\"kmp://msgmaybenotdelivered\"><img src=\":/img/mail-t2x16.png\"/></a></span>");
                msg.append(culast);
                msg.append("false");
                ui->tbChat->append(msg.at(0));
                msgs->beginGroup("Chat");
                msgs->setValue("LastMessageFrom","You");
                msgs->setValue("LastMessageID",cultid);
                msgs->endGroup();
                msgs->beginGroup("Messages");
                msgs->setValue("Message" + QString::number(cultid),msg);
                msgs->endGroup();
            }
        }
    }
    else
    {
        ui->txtMessageBox->clear();
        if (culast != "KM")
        {
            culast = "KM";
            QStringList msg;
            msg.append("<span style=\"color: red\">" + QString(ProductName) + "</span><br><span>" + QApplication::tr("You are offline") + "</span>");
            ui->tbChat->append(msg.at(0));
        }
        else
        {
            culast = "KM";
            QStringList msg;
            msg.append("<span>" + QApplication::tr("You are offline") + "</span>");
            ui->tbChat->append(msg.at(0));
        }
    }
}

QString frmChat::convertMessage(QString message)
{
    message = " " + message + " ";
    message = message.replace(QRegExp(" ((?:https?|ftp)://\\S+) "), " <a href=\"\\1\">\\1</a> ");
    message = message.replace(QRegExp(" ((?:mtasa)://\\S+) "), " <a href=\"\\1\">\\1</a> ");
    message = message.replace(" :) "," <img src=':/img/friendly.png'/> ");
    message = message.replace(" :-) "," <img src=':/img/friendly.png'/> ");
    message = message.replace(" ;) "," <img src=':/img/wink.png'/> ");
    message = message.replace(" ;-) "," <img src=':/img/wink.png'/> ");
    message = message.replace(" :| "," <img src=':/img/normal.png'/> ");
    message = message.replace(" :-| "," <img src=':/img/normal.png'/> ");
    message = message.replace(" :D "," <img src=':/img/laughting.png'/> ");
    message = message.replace(" :-D "," <img src=':/img/laughting.png'/> ");
    message = message.replace(" :P "," <img src=':/img/haha.png'/> ");
    message = message.replace(" :-P "," <img src=':/img/haha.png'/> ");
    message = message.replace(" :O "," <img src=':/img/surprised.png'/> ");
    message = message.replace(" :-O "," <img src=':/img/surprised.png'/> ");
    message = message.replace(" :( "," <img src=':/img/sad.png'/> ");
    message = message.replace(" :-( "," <img src=':/img/sad.png'/> ");
    message = message.replace(" ;( "," <img src=':/img/cry.png'/> ");
    message = message.replace(" ;-( "," <img src=':/img/cry.png'/> ");
    message = message.replace(" (cry) "," <img src=':/img/cry.png'/> ");
    message = message.replace(" (angry) "," <img src=':/img/angry.png'/> ");
    message = message.replace(" (evil) "," <img src=':/img/evil.png'/> ");
    message = message.trimmed();
    return message;
}

void frmChat::on_txtMessageBox_returnPressed()
{
    sendMessage();
}

void frmChat::on_cmdSmiley_clicked()
{
    QMenu *smileyContext = new QMenu();
    QAction *evilSmiley = smileyContext->addAction(QIcon(":/img/evil.png"),"(evil)");
    connect(evilSmiley,SIGNAL(triggered()),this,SLOT(addEvilSmiley()));
    QAction *friendlySmiley = smileyContext->addAction(QIcon(":/img/friendly.png"),":)");
    connect(friendlySmiley,SIGNAL(triggered()),this,SLOT(addFriendlySmiley()));
    QAction *winkSmiley = smileyContext->addAction(QIcon(":/img/wink.png"),";)");
    connect(winkSmiley,SIGNAL(triggered()),this,SLOT(addWinkSmiley()));
    QAction *laughtingSmiley = smileyContext->addAction(QIcon(":/img/laughting.png"),":D");
    connect(laughtingSmiley,SIGNAL(triggered()),this,SLOT(addLaughtingSmiley()));
    QAction *hahaSmiley = smileyContext->addAction(QIcon(":/img/haha.png"),":P");
    connect(hahaSmiley,SIGNAL(triggered()),this,SLOT(addHahaSmiley()));
    QAction *surprisedSmiley = smileyContext->addAction(QIcon(":/img/surprised.png"),":O");
    connect(surprisedSmiley,SIGNAL(triggered()),this,SLOT(addSurprisedSmiley()));
    QAction *normalSmiley = smileyContext->addAction(QIcon(":/img/normal.png"),":|");
    connect(normalSmiley,SIGNAL(triggered()),this,SLOT(addNormalSmiley()));
    QAction *sadSmiley = smileyContext->addAction(QIcon(":/img/sad.png"),":(");
    connect(sadSmiley,SIGNAL(triggered()),this,SLOT(addSadSmiley()));
    QAction *angrySmiley = smileyContext->addAction(QIcon(":/img/angry.png"),"(angry)");
    connect(angrySmiley,SIGNAL(triggered()),this,SLOT(addAngrySmiley()));
    QAction *crySmiley = smileyContext->addAction(QIcon(":/img/cry.png"),"(cry)");
    connect(crySmiley,SIGNAL(triggered()),this,SLOT(addCrySmiley()));
    smileyContext->popup(QCursor::pos());
}

void frmChat::appendTextToLineEdit(QLineEdit *lineedit, QString text)
{
    QString ntext = lineedit->text();
    ntext = ntext + text;
    lineedit->setText(ntext);
    lineedit->setFocus();
}

void frmChat::addEvilSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," (evil) ");
}

void frmChat::addFriendlySmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :) ");
}

void frmChat::addWinkSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," ;) ");
}

void frmChat::addLaughtingSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :D ");
}

void frmChat::addHahaSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :P ");
}

void frmChat::addSurprisedSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :O ");
}

void frmChat::addNormalSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :| ");
}

void frmChat::addSadSmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," :( ");
}

void frmChat::addAngrySmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," (angry) ");
}

void frmChat::addCrySmiley()
{
    appendTextToLineEdit(ui->txtMessageBox," (cry) ");
}

void frmChat::setChatFocus()
{
    ui->txtMessageBox->setFocus();
}

void frmChat::openLink(QString url)
{
    if (url == "kmp://msgmaybenotdelivered")
    {
        QMessageBox::information(this,QApplication::tr("Message"),QApplication::tr("This message was maybe not delivered"));
    }
    else
    {
        QDesktopServices::openUrl(QUrl(url));
    }
}

void frmChat::on_tbChat_sourceChanged(const QUrl &arg1)
{
    openLink(arg1.toString());
}

void frmChat::scrollDown()
{
    oldValue = ui->tbChat->verticalScrollBar()->maximum();
    ui->tbChat->verticalScrollBar()->setValue(ui->tbChat->verticalScrollBar()->maximum());
}

void frmChat::resizeEvent(QResizeEvent *ev)
{
    if (ui->tbChat->verticalScrollBar()->value() == ui->tbChat->verticalScrollBar()->maximum() || ui->tbChat->verticalScrollBar()->value() == oldValue)
    {
        QTimer::singleShot(10,this,SLOT(scrollDown()));
    }
    ev->accept();
}

void frmChat::on_cmdSmiley_mouseRelease(QMouseEvent *)
{
    if (ui->cmdSmiley->rect().contains(ui->cmdSmiley->mapFromGlobal(QCursor::pos())))
    {
        on_cmdSmiley_clicked();
    }
}

void frmChat::setWidgetDesign()
{
#ifdef QT4
    QStyle *KMStyle = QStyleFactory::create("cleanlooks");
    QStyle *KMAStyle = QStyleFactory::create("plastique");
#else
#ifdef QT5
    QStyle *KMStyle = QStyleFactory::create("fusion");
#else
    QCommonStyle *KMStyle = new QCommonStyle();
#endif
#endif
    ui->frBox->setStyle(KMStyle);
    ui->frChat->setStyle(KMStyle);
    ui->frUser->setStyle(KMStyle);
#ifdef QT4
    ui->frAvatar->setStyle(KMAStyle);
    ui->frAvatar->setMinimumSize(132,132);
    ui->frAvatar->setMaximumSize(132,132);
#else
    ui->frAvatar->setStyle(KMStyle);
    //ui->frAvatar->setStyleSheet("QFrame#frAvatar{background-color: rgb(215, 90, 0);}");
#endif
    QStyle *TStyle = QStyleFactory::create(qApp->style()->objectName());
    ui->txtMessageBox->setStyle(TStyle);
    ui->tbChat->setStyle(TStyle);
}
